Skip to content

Conversation

@lsy1307
Copy link
Contributor

@lsy1307 lsy1307 commented Jul 3, 2025

관련 이슈

작업 내용

  • 댓글 정책이 현재 삭제시 -> Content 삭제, 부모 댓글이 없을 시 Hard Delete로 구현에서
    모든 Content보존 -> isDeleted true로 변경하는 것으로 바뀌었으므로 이에 따라 수정사항을 적용합니다.
  • Comment isDeleted Column추가
  • HardDelete 로직 삭제, isDeleted true일시 Service레이어에서 content를 비운 채로 반환
  • 필요 없어진 테스트 코드 삭제 및 새로 추가된 로직 테스트 코드 추가

특이 사항

  • 이번 PR도 이전 branch에서 이어서 작업하였습니다.

리뷰 요구사항 (선택)

  • 이번 PR도 로직 위주로 봐주시면 감사하겠습니다 ( _ _ )

lsy1307 added 11 commits July 1, 2025 15:39
- Application, Country, GpaScore, InterestedCountry/Region, LanguageTestScore, LikedUniversity. SiteUser, UnivApplyInfo 도메인 수정
- 연관관계 삭제 및 생성자 parameter 수정으로 인한 쿼리 수정 다수
- test코드 수정
- 연관관계 변경에 따른 transaction 문제 해결
- 쿼리 일부 수정, 테스트 코드 일부 수정
- GeneralUniversityRecommendService 로직 수정
- ScoreService에서 siteUser정보를 다시 불러오는 로직 삭제
- 컨벤션, 타입수정 다수
- Board, Comment, Post, PostLike 연관관계 수정/삭제
- 연관관계 수정에 따른 Repository및 Service 레이어 수정
- 연관관계 수정에 따른 테스트 코드 수정
- is_deleted Column추가
- 해당 Column추가에 따른 Repository, Service, DTO 수정
- 댓글 삭제 시 content 보존하도록 변경
- 테스트 코드 수정
@coderabbitai
Copy link

coderabbitai bot commented Jul 3, 2025

Walkthrough

  1. Comment 엔티티 구조 변경

    • 기존 SiteUser 객체 참조를 제거하고, siteUserId 필드(long 타입)로 대체하였습니다.
    • 댓글 삭제 방식이 소프트 딜리트(삭제 플래그)로 변경되어, isDeleted(boolean, 기본값 false) 필드가 추가되었습니다.
    • SiteUser와의 양방향 관계 관리 코드가 모두 삭제되었습니다.
    • 댓글 삭제 시 content를 null로 만드는 대신 isDeleted를 true로 설정합니다.
    • resetPostAndSiteUserAndParentComment() 메서드는 resetPostAndParentComment()로 이름이 바뀌고, SiteUser 관련 처리가 사라졌습니다.
  2. 댓글 응답 DTO(PostFindCommentResponse) 로직 변경

    • from 팩토리 메서드가 SiteUser 객체를 추가 파라미터로 받도록 변경되었습니다.
    • 댓글이 삭제된 경우, 내용은 빈 문자열로, 사용자 정보는 null로 응답하도록 분기 처리 로직이 추가되었습니다.
  3. 댓글 트리 조회 쿼리 수정

    • findCommentTreeByPostId 쿼리에 is_deleted 컬럼이 포함되어, 각 댓글의 삭제 여부를 쿼리 결과로 확인할 수 있게 되었습니다.
  4. CommentService 주요 로직 변경

    • 댓글 조회 시, 부모 댓글과 모든 자식 댓글이 삭제된 경우 해당 트리 전체를 응답에서 제외하는 필터링 로직이 추가되었습니다.
    • 댓글 소유자 판별 및 검증 로직이 siteUserId 값 비교로 단순화되었습니다.
    • 댓글 생성, 삭제, 소유권 검증 등에서 SiteUser 객체 대신 siteUserId를 사용하도록 변경되었습니다.
    • 삭제 시 siteUser 관련 리셋 로직이 제거되었습니다.
  5. 테스트 코드 보강 및 변경

    • 댓글 소프트 딜리트 및 필터링 로직을 검증하는 테스트 3종이 추가되었습니다.
    • 댓글 삭제 후 content가 null이 아닌 기존 내용 유지 및 isDeleted 플래그가 true임을 확인하는 식으로 검증 방식이 바뀌었습니다.
    • 삭제된 부모 댓글과 자식 댓글이 모두 삭제된 경우 응답에서 제외되는지, 삭제된 부모 댓글의 사용자 정보가 null로 반환되는지 등을 검증합니다.
    • siteUserId 기반 검증으로 테스트 코드가 일부 수정되었습니다.
    • 부모-자식 댓글 모두 삭제 시 부모까지 삭제되는 테스트는 제거되었습니다.
  6. DB 마이그레이션

    • comment 테이블에 is_deleted BOOLEAN NOT NULL DEFAULT FALSE 컬럼이 추가되었습니다.

Suggested reviewers

  • Gyuhyeok99

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd85b32 and 6526fd1.

📒 Files selected for processing (1)
  • src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🔭 Outside diff range comments (1)
src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java (1)

78-89: 조인된 Region 엔티티 사용 일관성 점검 및 수정
아래 변경 사항을 반영해 주세요.

  1. Region 조인 제거
    join(university.region, region) 구문은 where 절에서 활용되지 않으므로 제거해야 합니다.
  2. regionCodeEq 메서드 수정
    필터를 country.regionCode 대신 join한 region 엔티티의 code 컬럼으로 변경하려면 region.code.eq(regionCode)로 메서드를 업데이트하세요.
  3. 불필요한 import 및 변수 삭제
    사용되지 않는 QRegion import와 region 변수 선언을 제거해 코드 가독성을 높입니다.
♻️ Duplicate comments (1)
src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java (1)

30-39: 🔄 InterestedCountry와 일관된 패턴으로 잘 변경되었습니다

전체 코드베이스에서 일관성 있게 ID 기반 참조로 변경하는 패턴이 잘 적용되었습니다.

InterestedCountry와 마찬가지로 siteUserId의 primitive long 타입 사용에 대한 동일한 고려사항이 있습니다.

🧹 Nitpick comments (9)
src/main/java/com/example/solidconnection/community/post/service/PostLikeService.java (1)

25-25: 🔍 사용하지 않는 의존성 제거를 고려해보세요

SiteUserRepository가 더 이상 이 서비스에서 사용되지 않는 것으로 보입니다. 코드를 정리하기 위해 제거하는 것을 고려해보세요.

-    private final SiteUserRepository siteUserRepository;
src/main/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendService.java (1)

26-29: 🎯 캐시 제거와 실시간 조회로의 변경이 적절합니다

변경사항의 장점:

  1. 애플리케이션 시작 시 초기화 비용 제거
  2. 메모리 사용량 감소
  3. 항상 최신 데이터 제공

@Transactional(readOnly = true) 사용으로 읽기 전용 최적화도 잘 적용되었습니다.

만약 이 메서드의 호출 빈도가 매우 높다면, 캐싱 전략(예: Spring Cache with TTL)을 고려해보는 것도 좋을 것 같습니다.

src/main/java/com/example/solidconnection/score/domain/GpaScore.java (1)

40-40: ⚠️ @column 어노테이션 추가를 고려해주세요

다른 엔티티들(InterestedCountry, InterestedRegion)과의 일관성을 위해 @Column 어노테이션을 추가하는 것이 좋겠습니다.

+    @Column(name = "site_user_id")
     private long siteUserId;
src/main/java/com/example/solidconnection/application/domain/Application.java (1)

79-133: 생성자 파라미터 개선 제안

현재 생성자들이 여전히 SiteUser 엔티티를 받아서 ID만 추출하고 있습니다. ID 기반 참조로 완전히 전환하려면 생성자 파라미터도 long siteUserId로 변경하는 것이 더 명확할 것 같습니다.

예시:

 public Application(
-        SiteUser siteUser,
+        long siteUserId,
         Gpa gpa,
         LanguageTest languageTest,
         String term) {
-    this.siteUserId = siteUser.getId();
+    this.siteUserId = siteUserId;

이렇게 하면 호출하는 쪽에서 명시적으로 ID를 전달하게 되어 의도가 더 명확해집니다.

src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java (1)

40-40: 데이터베이스 매핑을 위한 @column 어노테이션 추가를 고려하세요

명시적인 컬럼 매핑을 위해 @Column 어노테이션 추가를 권장합니다. 특히 컬럼명이나 nullable 속성을 명확히 하는 것이 좋습니다.

+    @Column(name = "site_user_id", nullable = false)
     private long siteUserId;
src/main/java/com/example/solidconnection/community/post/service/PostQueryService.java (1)

51-52: Board 검증 로직 최적화를 고려하세요

현재 구현은 Board 존재 여부만 확인하고 결과를 사용하지 않습니다. existsByCode 메소드를 사용하면 더 효율적일 수 있습니다.

Board 존재 여부만 확인하는 경우, Repository에 existsByCode 메소드를 추가하여 사용하는 것이 더 효율적입니다.

src/main/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepository.java (1)

28-28: 파라미터 타입 일관성 개선 필요

univApplyInfoId 파라미터가 Long wrapper 타입으로 선언되어 있는데, 다른 메서드들은 primitive long을 사용하고 있습니다. 일관성을 위해 primitive 타입으로 통일하는 것이 좋겠습니다.

-boolean existsBySiteUserIdAndUnivApplyInfoId(long siteUserId, Long univApplyInfoId);
+boolean existsBySiteUserIdAndUnivApplyInfoId(long siteUserId, long univApplyInfoId);
src/main/java/com/example/solidconnection/community/comment/domain/Comment.java (2)

50-51: 컬럼명 명시 권장

siteUserId 필드에 컬럼명을 명시하면 데이터베이스 스키마가 더 명확해집니다.

-@Column
+@Column(name = "site_user_id", nullable = false)
 private long siteUserId;

107-109: 소프트 삭제 로직 변경이 완벽합니다!

기존의 content nullify 방식에서 isDeleted 플래그 방식으로 변경한 것이 훌륭합니다:

  • 데이터 보존으로 감사 추적 가능
  • 필요시 복구 가능
  • 데이터 무결성 향상

다만, 메서드명을 더 명확하게 변경하는 것을 고려해보세요:

-public void deprecateComment() {
+public void softDelete() {
     this.isDeleted = true;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe7aefc and 1a00a77.

📒 Files selected for processing (60)
  • src/main/java/com/example/solidconnection/application/domain/Application.java (3 hunks)
  • src/main/java/com/example/solidconnection/application/dto/ApplicantsResponse.java (2 hunks)
  • src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java (2 hunks)
  • src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java (3 hunks)
  • src/main/java/com/example/solidconnection/community/board/domain/Board.java (0 hunks)
  • src/main/java/com/example/solidconnection/community/board/repository/BoardRepository.java (0 hunks)
  • src/main/java/com/example/solidconnection/community/comment/domain/Comment.java (4 hunks)
  • src/main/java/com/example/solidconnection/community/comment/dto/CommentCreateRequest.java (1 hunks)
  • src/main/java/com/example/solidconnection/community/comment/dto/PostFindCommentResponse.java (3 hunks)
  • src/main/java/com/example/solidconnection/community/comment/repository/CommentRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/community/comment/service/CommentService.java (5 hunks)
  • src/main/java/com/example/solidconnection/community/post/domain/Post.java (3 hunks)
  • src/main/java/com/example/solidconnection/community/post/domain/PostLike.java (1 hunks)
  • src/main/java/com/example/solidconnection/community/post/dto/PostCreateRequest.java (1 hunks)
  • src/main/java/com/example/solidconnection/community/post/repository/PostLikeRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/community/post/repository/PostRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/community/post/service/PostCommandService.java (3 hunks)
  • src/main/java/com/example/solidconnection/community/post/service/PostLikeService.java (3 hunks)
  • src/main/java/com/example/solidconnection/community/post/service/PostQueryService.java (5 hunks)
  • src/main/java/com/example/solidconnection/location/country/domain/Country.java (1 hunks)
  • src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java (2 hunks)
  • src/main/java/com/example/solidconnection/location/country/repository/InterestedCountryRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java (2 hunks)
  • src/main/java/com/example/solidconnection/location/region/repository/InterestedRegionRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/score/domain/GpaScore.java (1 hunks)
  • src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java (1 hunks)
  • src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java (2 hunks)
  • src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java (2 hunks)
  • src/main/java/com/example/solidconnection/score/service/ScoreService.java (1 hunks)
  • src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java (0 hunks)
  • src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java (3 hunks)
  • src/main/java/com/example/solidconnection/university/domain/LikedUnivApplyInfo.java (2 hunks)
  • src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java (2 hunks)
  • src/main/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java (2 hunks)
  • src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java (2 hunks)
  • src/main/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendService.java (2 hunks)
  • src/main/java/com/example/solidconnection/university/service/UnivApplyInfoLikeService.java (3 hunks)
  • src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java (1 hunks)
  • src/main/resources/data.sql (1 hunks)
  • src/main/resources/secret (1 hunks)
  • src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/community/board/repository/BoardRepositoryForTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixtureBuilder.java (1 hunks)
  • src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java (5 hunks)
  • src/test/java/com/example/solidconnection/community/post/fixture/PostFixtureBuilder.java (1 hunks)
  • src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java (2 hunks)
  • src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java (2 hunks)
  • src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/location/country/fixture/CountryFixtureBuilder.java (1 hunks)
  • src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixtureBuilder.java (0 hunks)
  • src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixtureBuilder.java (0 hunks)
  • src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java (2 hunks)
  • src/test/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepositoryTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendServiceTest.java (0 hunks)
  • src/test/java/com/example/solidconnection/university/service/UnivApplyInfoLikeServiceTest.java (3 hunks)
  • src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java (2 hunks)
💤 Files with no reviewable changes (6)
  • src/test/java/com/example/solidconnection/university/service/GeneralUnivApplyInfoRecommendServiceTest.java
  • src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixtureBuilder.java
  • src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixtureBuilder.java
  • src/main/java/com/example/solidconnection/community/board/repository/BoardRepository.java
  • src/main/java/com/example/solidconnection/community/board/domain/Board.java
  • src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (90)
src/main/resources/secret (1)

1-1: 서브모듈 커밋 포인터 업데이트 – 추가 체크 필요

  1. secret 서브모듈이 84002e8… 커밋으로 이동했습니다.
    • .gitmodules 및 CI/CD 캐시 무효화 설정이 함께 수정됐는지 확인해주세요.
  2. 새 커밋이 댓글 삭제 정책 변경 사항을 포함하는지, 로컬에서 git submodule update --init --recursive 로 재현 테스트를 권장합니다.
src/test/java/com/example/solidconnection/community/post/fixture/PostFixtureBuilder.java (1)

74-74: 도메인 엔티티 리팩터링에 맞춘 적절한 변경사항

엔티티 객체 대신 ID 값을 전달하도록 변경된 부분이 올바르게 적용되었습니다. 이는 도메인 모델에서 연관관계를 단순화하려는 전체적인 리팩터링 방향과 일치합니다.

변경 내용 정리:

  1. 객체 참조 → ID 참조: board.getCode(), siteUser.getId() 전달
  2. 일관성 확보: 다른 엔티티들의 변경사항과 동일한 패턴 적용
src/test/java/com/example/solidconnection/location/country/fixture/CountryFixtureBuilder.java (1)

40-40: Country 엔티티 생성자 변경이 올바르게 적용됨

Region 객체 대신 region 코드를 전달하도록 변경된 부분이 도메인 모델 리팩터링과 일치합니다.

변경 내용 정리:

  1. 엔티티 참조 제거: region 객체 → region.getCode() 문자열
  2. 테스트 일관성: 도메인 모델 변경사항과 동일한 패턴 적용
src/test/java/com/example/solidconnection/community/board/repository/BoardRepositoryForTest.java (1)

12-12: Board 엔티티 연관관계 제거에 맞춘 쿼리 수정

LEFT JOIN FETCH 절을 제거하여 Board 엔티티에서 postList 연관관계가 삭제된 것을 반영했습니다.

변경 내용 정리:

  1. Eager Loading 제거: postList 컬렉션 즉시 로딩 삭제
  2. 단순화된 쿼리: Board 엔티티만 조회하도록 변경
  3. 도메인 모델 일치: 엔티티 연관관계 단순화와 일관성 유지
src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java (1)

96-96: Post 엔티티 필드 변경에 맞춘 테스트 로직 수정

Board 엔티티 참조가 boardCode 필드로 변경된 것을 반영하여 테스트 로직이 올바르게 수정되었습니다.

변경 내용 정리:

  1. 메서드 호출 변경: post.getBoard().getCode()post.getBoardCode()
  2. 필터링 로직 유지: 게시판 코드 기반 필터링 동작 동일하게 유지
  3. 테스트 일관성: 도메인 모델 변경사항과 동기화

Also applies to: 118-118

src/main/resources/data.sql (1)

44-44: 승인: SiteUser 테이블 컬럼명 변경 일치 확인

  1. 컬럼명 변경
    • preparation_stageexchange_status로 수정되었습니다.
  2. 마이그레이션 스크립트 적용
    • db/migration/V18__rename_preparation_status.sql에서 ALTER TABLE…RENAME COLUMN 구문이 확인되었습니다.
  3. 데이터 삽입 구문 반영
    • src/main/resources/data.sql의 INSERT 문에 exchange_status가 사용되고 있습니다.

위 단계를 통해 도메인 모델 리팩터링에 맞춰 스키마와 데이터 삽입 구문이 올바르게 업데이트된 것을 확인했습니다.

src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java (1)

40-40: 승인: 엔티티 ID 기반 참조 전환 일관성 확인 완료
아래 번호별 확인 결과, 서비스·도메인·테스트 전반에서 siteUser.getId() 패턴이 일관되게 적용되었습니다:

  1. 서비스 레이어
     UnivApplyInfoRecommendService, UnivApplyInfoLikeService 등 모든 findBy… 메서드에서 siteUser.getId()를 사용했습니다.
  2. 도메인 모델
     LanguageTestScore, GpaScore, Application 등 생성자 및 필드 초기화에서 siteUser.getId()를 저장했습니다.
  3. 테스트 코드
     FixtureBuilder 및 Repository/Service 단위 테스트에서 siteUser.getId() 패턴을 일관되게 활용했습니다.

이상으로 리팩터링 목표가 전역에 걸쳐 완벽히 적용되었음을 확인했습니다.

src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java (1)

87-87: 테스트 코드가 리팩터링에 맞게 올바르게 업데이트되었습니다.

Repository 메서드 시그니처 변경에 따라 테스트 코드가 정확히 수정되었습니다. 테스트의 검증 로직은 그대로 유지되면서 새로운 API에 맞게 조정되었습니다.

src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java (2)

82-82: 게시글 좋아요 테스트가 새로운 repository 메서드에 맞게 업데이트되었습니다.

  1. 메서드 시그니처 변경 반영: findPostLikeByPostAndSiteUser에서 findPostLikeByPostAndSiteUserId로 변경
  2. 매개변수 조정: SiteUser 엔티티 대신 user.getId()를 전달하도록 수정

테스트의 검증 의도는 그대로 유지되면서 리팩터링에 정확히 대응되었습니다.


120-120: 좋아요 취소 테스트도 일관되게 업데이트되었습니다.

좋아요 생성 테스트와 동일한 패턴으로 repository 메서드 호출이 수정되어 일관성이 유지되었습니다.

src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java (2)

73-73: QueryDSL 조인 방식이 엔티티 구조 변경에 맞게 올바르게 수정되었습니다.

  1. 암시적 조인 제거: languageTestScore.siteUser 연관관계 제거
  2. 명시적 조인 적용: on(languageTestScore.siteUserId.eq(siteUser.id)) 조건 추가

LanguageTestScore 엔티티에서 SiteUser 연관관계가 siteUserId 필드로 변경된 것에 정확히 대응하는 수정입니다.


87-87: 카운트 쿼리도 동일한 방식으로 일관되게 수정되었습니다.

메인 쿼리와 카운트 쿼리 모두 동일한 조인 방식을 사용하여 일관성이 유지되었습니다.

src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java (2)

59-59: 사용자 기반 지원자 조회 메서드가 올바르게 수정되었습니다.

  1. 메서드명 변경: getApplicationBySiteUserAndTerm에서 getApplicationBySiteUserIdAndTerm로 변경
  2. 매개변수 수정: SiteUser 엔티티 대신 siteUser.getId()를 전달

Application 엔티티의 구조 변경에 정확히 맞춰 서비스 레이어가 업데이트되었습니다.


123-123: 지원자 조회 권한 검증 메서드도 일관되게 수정되었습니다.

같은 repository 메서드를 호출하는 다른 부분도 동일한 패턴으로 수정되어 코드 전체의 일관성이 유지되었습니다.

src/test/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepositoryTest.java (1)

82-87: 도메인 모델 변경에 맞춘 일관된 리팩터링입니다

엔티티 참조에서 ID 기반 참조로의 전환이 올바르게 적용되었습니다:

  1. 일관된 변경 적용: siteUser 객체 대신 siteUser.getId() 사용
  2. 명확한 의존성 관계: univApplyInfo 객체 대신 univApplyInfo.getId() 사용
  3. 테스트 로직 유지: 기존 테스트의 의도와 검증 로직은 그대로 유지

이러한 변경으로 엔티티 간의 결합도를 낮추고 더 명확한 의존성 관계를 구축했습니다.

src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java (1)

80-80: 동시성 테스트에서도 일관된 ID 기반 참조 적용

엔티티 참조에서 ID 기반 참조로의 전환이 동시성 테스트에서도 올바르게 적용되었습니다:

  1. 보드 코드 활용: board.getCode()를 통한 보드 식별자 사용
  2. 사용자 ID 활용: siteUser.getId()를 통한 사용자 식별자 사용
  3. 테스트 무결성 유지: 동시성 테스트의 핵심 로직은 변경되지 않음

이 변경으로 Post 엔티티의 새로운 설계와 일치하는 테스트 코드가 되었습니다.

src/main/java/com/example/solidconnection/community/comment/repository/CommentRepository.java (1)

15-34: 댓글 소프트 삭제 정책을 위한 쿼리 업데이트

재귀 쿼리에 is_deleted 컬럼이 올바르게 추가되어 새로운 댓글 삭제 정책을 지원합니다:

  1. CTE 기본 쿼리: 루트 댓글 조회 시 is_deleted 컬럼 포함 (19번 줄)
  2. 재귀 쿼리: 하위 댓글 조회 시에도 is_deleted 컬럼 포함 (26번 줄)
  3. 완전한 트리 구조: 모든 댓글 계층에서 삭제 상태 정보 제공

이 변경으로 서비스 레이어에서 삭제된 댓글의 내용을 비우고 삭제 상태를 관리할 수 있는 기반이 마련되었습니다.

src/main/java/com/example/solidconnection/community/comment/dto/CommentCreateRequest.java (1)

20-32: DTO에서 엔티티 생성 시 ID 기반 참조 적용

Comment 엔티티 생성 시 사용자 참조 방식이 일관되게 변경되었습니다:

  1. 루트 댓글 생성: setPostAndSiteUsersiteUser.getId() 전달 (27번 줄)
  2. 대댓글 생성: setParentCommentAndPostAndSiteUsersiteUser.getId() 전달 (29번 줄)
  3. 일관된 패턴: 모든 댓글 생성 경로에서 동일한 ID 기반 참조 사용

이러한 변경으로 Comment 도메인의 새로운 설계와 완벽히 일치하는 DTO 구조가 되었습니다.

src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixtureBuilder.java (1)

41-52: 테스트 픽스처에서 일관된 ID 기반 참조 적용

댓글 테스트 데이터 생성 시 새로운 도메인 모델에 맞춰 올바르게 수정되었습니다:

  1. 부모 댓글 생성: setPostAndSiteUsersiteUser.getId() 전달 (43번 줄)
  2. 자식 댓글 생성: 두 개의 setter 메서드 모두에 siteUser.getId() 전달 (49, 50번 줄)
  3. 일관된 패턴: 모든 댓글 생성 경로에서 동일한 방식 적용

테스트 픽스처가 새로운 Comment 엔티티 설계와 완벽히 일치하여 테스트 코드의 신뢰성을 보장합니다.

src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java (2)

196-198: 도메인 모델 리팩터링에 맞게 테스트 코드가 올바르게 수정되었습니다.

  1. 생성자 호출 변경: LikedUnivApplyInfo 생성자에서 엔티티 객체 대신 ID 값을 사용하도록 변경

    • univApplyInfoFixture.괌대학_A_지원_정보().getId()
    • testUser.getId()
  2. 일관성 유지: 도메인 엔티티의 연관관계 단순화에 맞춰 테스트 코드도 적절히 수정됨


203-203: 레포지토리 메서드 명 변경이 올바르게 반영되었습니다.

메서드 호출이 countBySiteUser_Id에서 countBySiteUserId로 변경되어 새로운 레포지토리 인터페이스 시그니처와 일치합니다.

src/main/java/com/example/solidconnection/community/post/dto/PostCreateRequest.java (1)

39-39: Post 엔티티의 메서드 시그니처 변경에 맞게 올바르게 수정되었습니다.

  1. 파라미터 변경: 엔티티 객체 대신 ID 값을 전달

    • board.getCode(): Board 엔티티 대신 보드 코드 사용
    • siteUser.getId(): SiteUser 엔티티 대신 사용자 ID 사용
  2. 일관성 유지: 도메인 레이어의 연관관계 단순화와 일치

src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java (1)

73-73: QueryDSL 조인 구문이 도메인 모델 변경에 맞게 올바르게 수정되었습니다.

  1. 조인 방식 변경:

    • 기존: 암시적 엔티티 조인 → 변경: 명시적 조인 + on 조건
    • .join(siteUser).on(gpaScore.siteUserId.eq(siteUser.id))
  2. 일관성 유지:

    • 데이터 조회 쿼리와 카운트 쿼리 모두 동일하게 수정됨
    • GpaScore 엔티티의 siteUserId 필드 사용으로 변경사항 반영

Also applies to: 87-87

src/main/java/com/example/solidconnection/application/dto/ApplicantsResponse.java (1)

8-8: 엔티티 비교를 ID 비교로 안전하게 변경했습니다.

  1. 안전한 비교 방식 도입:

    • Objects.equals() 사용으로 null 안전 비교 보장
    • auto-boxing/unboxing 이슈 방지
  2. 도메인 모델 변경 반영:

    • Application 엔티티의 getSiteUserId() 메서드 사용
    • 엔티티 연관관계 제거에 따른 적절한 수정

Also applies to: 28-28

src/main/java/com/example/solidconnection/location/region/repository/InterestedRegionRepository.java (1)

11-11: Spring Data JPA 메서드 시그니처가 도메인 모델 변경에 맞게 올바르게 수정되었습니다.

  1. 메서드 명 변경:

    • 기존: findAllBySiteUser(SiteUser siteUser)
    • 변경: findAllBySiteUserId(long siteUserId)
  2. 일관성 유지:

    • InterestedRegion 엔티티의 siteUserId 필드 사용
    • Spring Data JPA 명명 규칙 준수
src/main/java/com/example/solidconnection/location/country/repository/InterestedCountryRepository.java (1)

10-10: 일관성 검증 완료: siteUserId 기반 조회 일괄 적용 확인

모든 Repository 메서드에서 SiteUser 엔티티 대신 long siteUserId 파라미터 사용이 일관되게 적용되었습니다. 주요 변경사항을 간단히 정리합니다:

  1. News 모듈
    - NewsRepository: findAllBySiteUserIdOrderByUpdatedAtDesc(long siteUserId) 적용
    - NewsQueryService: 메서드 호출부에서 siteUserId 사용으로 변경
  2. UnivApplyInfo 모듈
    - UnivApplyInfoRepository: findAllBySiteUsersInterestedCountryOrRegionAndTerm(@param("siteUserId") Long siteUserId, String term)
    - UnivApplyInfoRecommendService: siteUser.getId() 전달로 변경
  3. LikedUnivApplyInfoRepository
    - findAllBySiteUserId(long siteUserId) 및 countBySiteUserId(long siteUserId) 적용
  4. Location 모듈
    - InterestedRegionRepository: findAllBySiteUserId(long siteUserId)
    - InterestedCountryRepository: findAllBySiteUserId(long siteUserId)

이상으로 전체 코드베이스에 리팩터링 목표가 충실히 반영되었음을 확인했습니다.

src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java (3)

11-11: 임포트 변경사항이 적절합니다.

LikedUnivApplyInfo에서 UnivApplyInfo로 변경하여 중간 매핑 엔티티를 제거한 것은 좋은 결정입니다.


42-42: ID 기반 메서드 호출로 변경한 점 좋습니다.

  1. 성능 개선: countBySiteUser_Id에서 countBySiteUserId로 변경하여 불필요한 조인을 제거했습니다.
  2. 일관성: 다른 Repository와 동일한 패턴을 따르고 있습니다.

98-102: 스트림 처리 로직이 크게 개선되었습니다.

  1. 코드 단순화: 중간 매핑 단계를 제거하여 코드가 더 직관적이 되었습니다.
  2. 성능 향상: 직접 UnivApplyInfo를 조회하여 불필요한 객체 생성을 방지했습니다.
  3. 가독성 향상: 메서드 참조 사용으로 코드가 더 깔끔해졌습니다.
src/test/java/com/example/solidconnection/university/service/UnivApplyInfoLikeServiceTest.java (3)

64-66: 테스트 어서션을 ID 기반으로 올바르게 변경했습니다.

  1. 일관성: 도메인 변경사항에 맞춰 테스트 코드를 정확히 업데이트했습니다.
  2. 명확성: ID 기반 조회로 테스트 의도가 더 명확해졌습니다.

96-98: 좋아요 취소 테스트 로직이 적절합니다.

ID 기반 조회로 변경하여 테스트의 정확성을 유지했습니다.


155-158: 테스트 헬퍼 메서드가 올바르게 업데이트되었습니다.

  1. 빌더 패턴 적용: siteUserId와 univApplyInfoId를 직접 설정하여 명시적입니다.
  2. 테스트 데이터 생성: 실제 엔티티 대신 ID를 사용하여 테스트 데이터 생성이 단순화되었습니다.
src/main/java/com/example/solidconnection/community/post/repository/PostRepository.java (2)

18-18: 새로운 쿼리 메서드 추가가 적절합니다.

boardCode 기반으로 Post를 조회하는 메서드가 추가되어 Board 엔티티 없이도 관련 게시글을 조회할 수 있습니다.


19-19: EntityGraph 최적화가 잘 이루어졌습니다.

  1. 성능 개선: 불필요한 연관 엔티티 로딩을 제거하여 쿼리 성능이 향상됩니다.
  2. 일관성: 엔티티 연관관계 변경사항에 맞춰 필요한 것만 로딩하도록 조정했습니다.
  3. 명확성: postImageList만 eager loading하여 의도가 명확합니다.
src/main/java/com/example/solidconnection/community/post/service/PostCommandService.java (3)

28-28: Objects 임포트 추가가 적절합니다.

ID 비교를 위한 Objects.equals 사용을 위해 필요한 임포트입니다.


55-55: 게시글 생성 로직이 단순화되었습니다.

  1. 효율성: 별도의 SiteUser 조회 없이 전달받은 객체를 직접 사용합니다.
  2. 일관성: 엔티티 연관관계 변경사항에 맞춰 ID 기반으로 Post를 생성합니다.

109-109: 소유권 검증 로직이 올바르게 수정되었습니다.

  1. 안전성: Objects.equals 사용으로 null 안전성을 보장합니다.
  2. 정확성: ID 기반 비교로 소유권 검증이 정확하게 수행됩니다.
  3. 일관성: 다른 서비스 클래스와 동일한 패턴을 따르고 있습니다.
src/main/java/com/example/solidconnection/community/comment/dto/PostFindCommentResponse.java (2)

19-19: 메서드 시그니처 변경 승인

댓글 엔티티에서 사용자 연관관계가 제거되면서 SiteUser를 별도 파라미터로 받도록 변경된 것이 적절합니다.


37-39: 소프트 삭제 정책 구현 확인

삭제된 댓글의 내용을 빈 문자열로 반환하는 로직이 PR 목표와 일치합니다. 간단하고 명확한 구현입니다.

src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java (2)

143-145: 테스트 방식 변경 승인

캐시된 데이터에 의존하던 기존 방식에서 반환 데이터의 속성 검증으로 변경된 것이 적절합니다. 서비스 계층의 아키텍처 변경에 맞춰 테스트도 유연하게 대응되었습니다.


155-156: 일반 추천 테스트 로직 개선

속성 기반 검증으로 변경되어 테스트가 더 안정적이고 유지보수하기 쉬워졌습니다.

src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java (2)

81-81: 점수 조회 메서드 변경 승인

GPA 점수와 어학 점수 조회에서 사용자 ID를 사용하는 것이 리팩터링 목표와 일치합니다. 로직이 명확하고 올바릅니다.

Also applies to: 91-91


53-53: 레포지토리 메서드 호출 검증 완료

  1. 변경 내역 검토
    siteUser.getId() 사용이 적절합니다.
  2. 메서드 존재 확인
    ApplicationRepository.java 41번 라인에서 findBySiteUserIdAndTerm 메서드가 정의되어 있습니다.
  3. 추가 조치
    별도의 수정은 필요 없습니다.

이상으로 모든 검증이 완료되었습니다.

src/main/java/com/example/solidconnection/university/service/UnivApplyInfoLikeService.java (2)

41-41: ID 기반 레포지토리 메서드 사용 승인

  1. 좋아요 조회 로직이 ID 기반으로 일관되게 변경되었습니다.
  2. 좋아요 취소 로직도 동일한 방식으로 업데이트되었습니다.
  3. 좋아요 상태 확인 로직도 올바르게 적용되었습니다.

엔티티 연관관계 제거에 따른 자연스러운 변경입니다.

Also applies to: 61-61, 76-76


47-48: 엔티티 생성 로직 개선

빌더 패턴에서 ID 필드를 직접 설정하는 방식으로 변경되어 더 명확하고 간단해졌습니다.

src/main/java/com/example/solidconnection/location/country/domain/Country.java (2)

24-25: 엔티티 연관관계 단순화 승인

Region 엔티티 연관관계를 regionCode 문자열로 대체한 것이 전체 리팩터링 목표와 일치합니다. 데이터베이스 컬럼 매핑도 적절합니다.


27-27: 생성자 업데이트 확인

regionCode 필드 추가에 따라 생성자가 올바르게 업데이트되었습니다. 파라미터 순서와 필드 할당이 적절합니다.

Also applies to: 30-30

src/main/java/com/example/solidconnection/community/post/service/PostLikeService.java (3)

27-37: ✨ ID 기반 참조로의 변경이 적절합니다!

SiteUser 엔티티 대신 siteUser.getId()를 사용하여 좋아요를 생성하는 변경사항이 잘 적용되었습니다. 이는 도메인 모델의 변경사항과 일치하며, 불필요한 엔티티 로딩을 방지하여 성능 향상에 도움이 됩니다.


39-49: 👍 레포지토리 메서드 변경이 일관성 있게 적용되었습니다

getByPostAndSiteUserId 메서드가 사용자 ID를 직접 받도록 변경된 것이 확인됩니다. 전체적인 ID 기반 참조 패턴과 일치하는 좋은 변경입니다.


51-55: ✅ 검증 로직이 올바르게 수정되었습니다

중복 좋아요 검증 로직이 ID 기반으로 적절히 변경되었습니다.

src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java (2)

30-34: 📋 ID 기반 필드로의 변경이 잘 적용되었습니다

JPA 연관관계를 제거하고 ID 필드로 대체한 것은 좋은 선택입니다. @Column 어노테이션도 적절히 적용되었습니다.

다만, siteUserId를 primitive long 타입으로 선언한 것에 대해 확인이 필요합니다. null 값을 허용해야 하는 경우가 있는지 검토해주세요.


36-39: ✨ 생성자 변경이 깔끔하게 처리되었습니다

도메인 객체에서 ID를 추출하여 저장하는 방식이 명확하고 일관성 있게 구현되었습니다.

src/main/java/com/example/solidconnection/score/domain/GpaScore.java (1)

42-47: 👏 생성자 변경이 적절하게 처리되었습니다

SiteUser 엔티티에서 ID를 추출하여 저장하는 방식이 다른 엔티티들과 일관되게 구현되었습니다.

src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java (2)

1-17: PR 목표와 실제 코드 변경 사항 불일치

PR 목표에서는 댓글 삭제 정책 변경 (하드 삭제 → isDeleted 플래그 사용)을 언급하고 있으나, 실제 코드는 JPA 연관관계를 ID 기반 참조로 변경하는 대규모 리팩토링을 보여주고 있습니다. PR 목표를 업데이트하거나 올바른 파일들을 리뷰 대상으로 제공해 주시기 바랍니다.

Likely an incorrect or invalid review comment.


12-16: Repository 메서드 시그니처 변경 승인

엔티티 연관관계를 ID 기반으로 변경하는 리팩토링에 맞춰 Repository 메서드들이 적절히 수정되었습니다:

  • SiteUser 엔티티 파라미터 → long siteUserId 파라미터로 변경
  • 메서드명도 파라미터 변경을 반영하여 일관성 있게 수정됨
  • 새로운 findBySiteUserId 메서드 추가로 여러 GPA 점수 조회 가능

변경사항이 Spring Data JPA 컨벤션을 잘 따르고 있습니다.

src/main/java/com/example/solidconnection/application/domain/Application.java (1)

76-77: 필드 타입 선택 확인 필요

siteUserId 필드가 primitive long 타입으로 선언되어 있어 null 값을 가질 수 없습니다. 모든 Application이 반드시 사용자를 가져야 한다면 적절한 선택이지만, 선택적 관계라면 Long 타입 사용을 고려해 주세요.

src/main/java/com/example/solidconnection/score/service/ScoreService.java (2)

35-42: Repository 호출 방식 개선 확인

GpaScore 생성 로직이 적절히 수정되었습니다. 다만, GpaScore 생성자가 여전히 SiteUser 엔티티를 받는 것으로 보입니다. Domain 엔티티의 생성자도 ID를 직접 받도록 수정되었는지 확인이 필요합니다.


54-63: ID 기반 조회로의 전환 완료

findBySiteUserId 메서드를 사용하여 사용자 ID로 직접 조회하도록 변경된 점이 좋습니다. 이전의 엔티티 연관관계를 통한 조회보다 더 명확하고 효율적입니다.

src/main/java/com/example/solidconnection/community/post/domain/Post.java (2)

48-52: 엔티티 연관관계를 ID 참조로 변경 승인

Board와 SiteUser에 대한 @ManyToOne 연관관계를 ID 필드로 변경한 것이 적절합니다:

  • boardCode (String): Board 엔티티의 비즈니스 키 사용
  • siteUserId (long): SiteUser의 기본 키 사용

서로 다른 ID 타입을 사용하는 것이 의도적인지 확인해 주세요.


76-79: 메서드 시그니처 개선 확인

setBoardAndSiteUser 메서드가 엔티티 대신 ID를 직접 받도록 변경되어 의도가 명확해졌습니다. ID 기반 참조 패턴과 일관성 있게 구현되었습니다.

src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java (2)

31-38: JPQL 쿼리 및 메서드 시그니처 업데이트 승인

엔티티 연관관계 제거에 따른 Repository 변경사항이 일관성 있게 적용되었습니다:

  1. JPQL 쿼리에서 a.siteUserId 필드 직접 참조
  2. 메서드명 변경: findBySiteUserAndTermfindBySiteUserIdAndTerm
  3. 파라미터 타입 변경: SiteUserLong siteUserId

변경사항이 명확하고 적절합니다.


40-43: Default 메서드 일관성 유지 확인

getApplicationBySiteUserIdAndTerm default 메서드도 새로운 시그니처에 맞게 적절히 수정되었으며, 기존의 예외 처리 로직을 유지하고 있어 좋습니다.

src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java (2)

43-43: 쿼리 메서드 호출 업데이트가 올바르게 적용되었습니다

regionCodeEq 메서드의 시그니처 변경에 맞춰 호출 부분도 정확히 수정되었습니다.


50-55: 엔티티 연관관계 단순화가 적절하게 구현되었습니다

  1. 시그니처 변경: QRegion 대신 QCountry 파라미터 사용
  2. 필터링 로직 개선: country.regionCode를 직접 사용하여 조인 없이 필터링
  3. 성능 향상: 불필요한 조인 제거로 쿼리 성능 개선 기대

변경 사항이 전체 리팩터링 방향성과 일치합니다.

src/main/java/com/example/solidconnection/university/domain/LikedUnivApplyInfo.java (2)

3-3: 필요한 import 추가가 적절합니다

@Column 어노테이션 사용을 위한 import가 올바르게 추가되었습니다.


34-39: 엔티티 연관관계 단순화가 올바르게 적용되었습니다

  1. 필드 변경: @ManyToOne 연관관계를 primitive ID 필드로 변경
  2. 컬럼 매핑: @Column 어노테이션으로 명시적 컬럼 매핑
  3. 일관성 확인: 컬럼명이 @UniqueConstraint에 정의된 이름과 일치
// 기존: @ManyToOne UnivApplyInfo univApplyInfo
// 변경: @Column(name="university_info_for_apply_id") long univApplyInfoId

// 기존: @ManyToOne SiteUser siteUser  
// 변경: @Column(name="site_user_id") long siteUserId

엔티티 단순화 목표에 부합하는 변경사항입니다.

src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java (3)

14-14: 필요한 import 추가가 적절합니다

CascadeType.ALL 사용을 위한 import가 올바르게 추가되었습니다.


80-81: 엔티티 생명주기 관리가 개선되었습니다

  1. 캐스케이드 추가: cascade = CascadeType.ALL로 연관 엔티티 자동 저장/삭제
  2. 고아 객체 제거: orphanRemoval = true로 참조 해제된 객체 자동 삭제
  3. 데이터 무결성 향상: 부모-자식 엔티티 간 일관성 보장

이러한 변경은 LanguageRequirement 엔티티의 생명주기를 UnivApplyInfo에 완전히 종속시켜 데이터 무결성을 강화합니다.


83-84: 지연 로딩 적용으로 성능 최적화

  1. 성능 개선: EAGER에서 LAZY로 변경하여 불필요한 즉시 로딩 방지
  2. 메모리 효율성: 필요한 시점에만 대학교 정보 로딩
  3. N+1 문제 방지: 명시적 fetch join 사용 시점 제어 가능

지연 로딩 적용이 전체 성능 최적화 목표와 일치합니다.

src/main/java/com/example/solidconnection/community/post/repository/PostLikeRepository.java (2)

14-14: 리포지토리 메서드 시그니처 개선

  1. 파라미터 단순화: SiteUser 엔티티 대신 long siteUserId 사용
  2. 성능 향상: 엔티티 로딩 없이 ID만으로 조회 가능
  3. 메서드명 일관성: 파라미터 변경에 맞춰 메서드명도 적절히 수정

변경사항이 전체 리팩터링 방향성과 일치합니다.


16-19: 기본 메서드 구현 업데이트가 올바릅니다

  1. 일관성 유지: 새로운 메서드 시그니처에 맞춰 구현 수정
  2. 예외 처리: 기존과 동일한 예외 처리 로직 유지
  3. 편의성 제공: 여전히 Optional 체크와 예외 변환 기능 제공

기본 메서드 구현이 변경된 시그니처와 일치하게 정확히 수정되었습니다.

src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java (5)

112-135: 새로운 댓글 삭제 정책 테스트가 적절히 추가되었습니다

  1. 테스트 목적: 부모댓글과 모든 자식댓글이 삭제된 경우 응답에서 제외되는지 확인
  2. 테스트 시나리오:
    • 부모댓글 1개와 자식댓글 2개 생성
    • 모든 댓글을 deprecateComment()로 삭제 처리
    • 조회 결과에서 완전히 제외되는지 검증
  3. 검증 로직: 응답이 비어있고, 삭제된 댓글 ID들이 포함되지 않는지 확인

새로운 소프트 삭제 정책을 정확히 반영한 테스트입니다.


155-155: 엔티티 필드 접근 방식 업데이트

getSiteUser().getId() 대신 getSiteUserId() 직접 사용으로 변경되어 새로운 엔티티 구조와 일치합니다.


175-175: 엔티티 필드 접근 방식 업데이트

자식댓글 생성 테스트에서도 동일하게 getSiteUserId() 직접 사용으로 변경되었습니다.


232-232: 엔티티 필드 접근 방식 업데이트

댓글 수정 테스트에서도 일관되게 getSiteUserId() 직접 사용으로 변경되었습니다.


308-310: 소프트 삭제 정책 테스트 검증 로직 개선

  1. 내용 보존 확인: 삭제된 댓글의 내용이 그대로 유지되는지 검증
  2. 삭제 플래그 확인: isDeleted() 플래그가 true로 설정되는지 검증
  3. 정책 반영: 하드 삭제 대신 소프트 삭제 정책 적용 확인

새로운 댓글 삭제 정책이 올바르게 테스트되고 있습니다.

src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java (1)

17-17: 적절한 메소드 추가입니다

사용자별 모든 언어 시험 점수를 조회하는 메소드 추가가 ID 기반 리팩토링 패턴에 잘 맞습니다.

src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java (1)

42-46: 생성자 구현이 적절합니다

기존 API와의 호환성을 유지하면서 ID만 저장하는 방식으로 잘 구현되었습니다.

src/main/java/com/example/solidconnection/community/post/service/PostQueryService.java (2)

63-67: 명시적 엔티티 로딩이 잘 구현되었습니다

ID 기반 리팩토링에 따라 필요한 엔티티들을 명시적으로 로드하고, 적절한 예외 처리가 구현되었습니다.


89-96: ID 비교 로직이 적절히 구현되었습니다

Objects.equals를 사용한 null-safe ID 비교와 업데이트된 repository 메소드 사용이 적절합니다.

src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java (2)

19-38: JPQL 쿼리가 ID 기반 접근에 맞게 잘 수정되었습니다

서브쿼리를 통한 관심 국가/지역 조회와 LEFT JOIN FETCH 전략이 적절히 구현되었습니다.


63-70: Fetch 전략이 적절히 수정되었습니다

모든 연관관계에 대해 LEFT JOIN FETCH를 사용하는 것은 optional 연관관계 처리에 적합합니다.

src/main/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepository.java (2)

14-18: ID 기반 조회로의 전환이 적절합니다! 👍

엔티티 참조 대신 primitive ID를 사용하는 것은 다음과 같은 이점이 있습니다:

  1. 불필요한 엔티티 로딩 방지
  2. N+1 문제 회피
  3. 메모리 사용량 감소

메서드명도 일관성 있게 업데이트되었네요.


20-26: 효율적인 JPQL 쿼리 추가!

JOIN을 통해 UnivApplyInfo 엔티티를 직접 조회하도록 한 것은 훌륭한 선택입니다:

  • 서비스 레이어의 매핑 로직 간소화
  • 단일 쿼리로 필요한 데이터 조회
  • 성능 최적화
src/main/java/com/example/solidconnection/community/comment/domain/Comment.java (3)

43-45: 소프트 삭제 구현이 완벽합니다! 🎯

isDeleted 필드 추가로 다음과 같은 이점을 얻을 수 있습니다:

  1. 데이터 무결성 보장
  2. 삭제 이력 추적 가능
  3. 복구 가능성 확보

컬럼 정의도 적절합니다 (기본값 false, NOT NULL).


64-90: 엔티티 참조를 ID로 변경한 리팩토링이 깔끔합니다!

양방향 관계 관리 로직은 그대로 유지하면서 SiteUser 참조만 ID로 변경한 것이 좋습니다. 이로 인해:

  • 순환 참조 문제 방지
  • 메모리 사용량 감소
  • 영속성 컨텍스트 부담 감소

92-101: 메서드명 변경이 적절합니다!

resetPostAndSiteUserAndParentCommentresetPostAndParentComment으로 변경한 것이 현재 구조에 맞습니다. siteUserId는 primitive 타입이므로 별도 리셋이 불필요하죠.

src/main/java/com/example/solidconnection/community/comment/service/CommentService.java (3)

77-79: ID 기반 소유권 확인이 깔끔합니다! 👍

Objects.equals()를 사용하여 null-safe하게 비교하는 것이 좋습니다. primitive long 타입이지만 boxing되어 비교되므로 안전합니다.


150-154: 소유권 검증 로직이 적절합니다!

ID 기반 비교로 변경되었고, Objects.equals()를 사용하여 안전하게 비교합니다.


121-148: 삭제 정책 일관성 확인 필요

PR 설명에는 “모든 삭제를 소프트 삭제로 처리”라고 되어 있지만, 실제 구현에는 하드 삭제가 혼재되어 있습니다. 아래 세 가지 삭제 정책이 PR 의도와 일치하는지 확인 부탁드립니다.

  1. 대댓글 삭제 처리
    • 현재: resetPostAndParentComment() 후 deleteById로 하드 삭제
    • 제안: deprecateComment()로 소프트 삭제 일원화
  2. 자식 없는 댓글 삭제 처리
    • 현재: resetPostAndParentComment() 후 deleteById로 하드 삭제
    • 제안: deprecateComment()로 통일
  3. 자식 있는 댓글 삭제 처리
    • 현재: deprecateComment()로 소프트 삭제
    • 제안: 변경된 정책에 부합하므로 유지 가능

정책 일관성을 위해 위 항목을 검토해 주시고, 필요 시 아래와 같이 수정해 보세요.

     public CommentDeleteResponse deleteCommentById(SiteUser siteUser, Long commentId) {
         Comment comment = commentRepository.getById(commentId);
         validateOwnership(comment, siteUser);

         if (comment.getParentComment() != null) {
-            Comment parentComment = comment.getParentComment();
-            comment.resetPostAndParentComment();
-            commentRepository.deleteById(commentId);
-            if (parentComment.getCommentList().isEmpty() && parentComment.getContent() == null) {
-                parentComment.resetPostAndParentComment();
-                commentRepository.deleteById(parentComment.getId());
-            }
+            comment.deprecateComment();
         } else {
-            if (comment.getCommentList().isEmpty()) {
-                comment.resetPostAndParentComment();
-                commentRepository.deleteById(commentId);
-            } else {
-                comment.deprecateComment();
-            }
+            comment.deprecateComment();
         }
         return new CommentDeleteResponse(commentId);
     }

Comment on lines +53 to +75
private List<Comment> filterCommentsByDeletionRules(List<Comment> comments) {
Map<Long, List<Comment>> commentsByParent = comments.stream()
.filter(comment -> comment.getParentComment() != null)
.collect(Collectors.groupingBy(comment -> comment.getParentComment().getId()));

List<Comment> result = new ArrayList<>();

List<Comment> parentComments = comments.stream()
.filter(comment -> comment.getParentComment() == null)
.toList();
for (Comment parent : parentComments) {
List<Comment> children = commentsByParent.getOrDefault(parent.getId(), List.of());
boolean allDeleted = parent.isDeleted() &&
children.stream().allMatch(Comment::isDeleted);
if (!allDeleted) {
result.add(parent);
result.addAll(children.stream()
.filter(child -> !child.isDeleted())
.toList());
}
}
return result;
}
Copy link

@coderabbitai coderabbitai bot Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

댓글 필터링 로직 검토 필요 ⚠️

현재 로직에 몇 가지 문제점이 있습니다:

  1. 부모 댓글이 삭제되었지만 자식 중 일부만 삭제된 경우:

    • 현재: 부모 댓글은 포함되지만 삭제된 자식은 제외됨 (라인 69-72)
    • 문제: 삭제된 부모 댓글의 내용이 노출될 수 있음
  2. 결과 리스트 순서:

    • 재귀 쿼리로 가져온 원본 순서가 보장되지 않을 수 있음
 private List<Comment> filterCommentsByDeletionRules(List<Comment> comments) {
     Map<Long, List<Comment>> commentsByParent = comments.stream()
             .filter(comment -> comment.getParentComment() != null)
             .collect(Collectors.groupingBy(comment -> comment.getParentComment().getId()));

     List<Comment> result = new ArrayList<>();

     List<Comment> parentComments = comments.stream()
             .filter(comment -> comment.getParentComment() == null)
             .toList();
     for (Comment parent : parentComments) {
         List<Comment> children = commentsByParent.getOrDefault(parent.getId(), List.of());
         boolean allDeleted = parent.isDeleted() &&
                 children.stream().allMatch(Comment::isDeleted);
         if (!allDeleted) {
             result.add(parent);
-            result.addAll(children.stream()
-                    .filter(child -> !child.isDeleted())
-                    .toList());
+            result.addAll(children);
         }
     }
     return result;
 }

서비스 레이어가 아닌 PostFindCommentResponse에서 삭제된 댓글의 내용을 숨기는 것이 더 적절할 것 같습니다.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
src/main/java/com/example/solidconnection/community/comment/service/CommentService.java
lines 53 to 75, the current filterCommentsByDeletionRules method incorrectly
includes deleted parent comments when some child comments are not deleted,
exposing deleted content, and does not preserve the original comment order. To
fix this, adjust the logic to exclude any deleted parent comment regardless of
child status, and ensure the output list maintains the original order from the
input list. Additionally, consider moving the deletion content hiding logic from
the service layer to the PostFindCommentResponse DTO to better separate
concerns.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 테스트한 바로는 두 문제 모두 발생하지 않는 것 같습니다.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@whqtker 테스트 결과를 알려주셔서 감사합니다! 실제 동작을 확인해보신 결과가 이론적 분석보다 훨씬 신뢰할 만하네요.

  1. 콘텐츠 노출 문제: PostFindCommentResponse.from에서 getDisplayContent 메서드를 통해 삭제된 댓글의 내용을 숨기는 처리가 이미 되어 있군요.

  2. 순서 보장: findCommentTreeByPostId가 계층적 순서로 댓글을 반환하고, 현재 필터링 로직이 이를 적절히 유지하고 있는 것 같습니다.

실제 테스트를 통해 검증해주셔서 도움이 되었습니다. 코드가 의도한 대로 잘 동작하고 있다니 다행이네요! 🎉

Copy link
Member

@whqtker whqtker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

궁금한 점 코멘트 남겼습니다 ! 고생하셨습니다 ~!!!

private String content;

@Column(name = "is_deleted", columnDefinition = "boolean default false", nullable = false)
private boolean isDeleted;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#348 (comment)
columnDefinition 을 최대한 사용하지 않는 방향으로 진행하는 것 같습니다 ..! private boolean isDeleted = false; 로 작성하면 좋을 것 같습니다.

Copy link
Contributor

@Gyuhyeok99 Gyuhyeok99 Jul 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 월요일 회의 때 이야기를 더 나눠보면 좋을 것 같습니다!
[중요] flyway 스크립트 반영이 필요합니다!!!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 회의에서 이야기해보는게 좋겠습니다.!

Copy link
Contributor Author

@lsy1307 lsy1307 Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 회의에서 이야기한 대로 별도의 PR에서 진행하겠습니다.

comment.resetPostAndParentComment();
commentRepository.deleteById(commentId);
// 대댓글 삭제 이후, 부모댓글이 무의미하다면 이역시 삭제합니다.
if (parentComment.getCommentList().isEmpty() && parentComment.getContent() == null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isDeleted 필드를 추가했으니, 제 개인적인 생각엔 parentComment.getContent() == null 대신 parentComment.isDeleted() 가 의미를 더 잘 나타내는 것 같습니다 ! 물론 로직 동작은 전혀 변함이 없습니다. 반영 안 하셔도 됩니다 !

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 그게 더 좋겠다 생각합니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정하였습니다!

Comment on lines +53 to +75
private List<Comment> filterCommentsByDeletionRules(List<Comment> comments) {
Map<Long, List<Comment>> commentsByParent = comments.stream()
.filter(comment -> comment.getParentComment() != null)
.collect(Collectors.groupingBy(comment -> comment.getParentComment().getId()));

List<Comment> result = new ArrayList<>();

List<Comment> parentComments = comments.stream()
.filter(comment -> comment.getParentComment() == null)
.toList();
for (Comment parent : parentComments) {
List<Comment> children = commentsByParent.getOrDefault(parent.getId(), List.of());
boolean allDeleted = parent.isDeleted() &&
children.stream().allMatch(Comment::isDeleted);
if (!allDeleted) {
result.add(parent);
result.addAll(children.stream()
.filter(child -> !child.isDeleted())
.toList());
}
}
return result;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 테스트한 바로는 두 문제 모두 발생하지 않는 것 같습니다.

Copy link
Collaborator

@nayonsoso nayonsoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!
규혁님이 말씀하신 것처럼, flyway 스크립트 작성 잊지 마셔요!! 😊

private String content;

@Column(name = "is_deleted", columnDefinition = "boolean default false", nullable = false)
private boolean isDeleted;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 회의에서 이야기해보는게 좋겠습니다.!

Comment on lines 36 to 39
}
private static String getDisplayContent(Comment comment) {
return comment.isDeleted() ? "" : comment.getContent();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

두 함수 사이에 개행이 필요해보입니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정하였습니다!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트코드 보충이 필요해보여요! 서비스 로직에서 수행하고 있는 것은

  • 부모, 자식 댓글들이 모두 삭제되었다면 보여주지 않는다.
  • 부모 댓글이 삭제된 경우에도, 자식 댓글이 있으면 "삭제되지 않은 자식 댓글만" 보여준다.

이렇게 두가지인데, 첫번째에 대한 테스트만 존재하네요.!
두번째 로직에 대한 테스트가 추가되어야 할 것 같습니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가하였습니다!

Copy link
Collaborator

@nayonsoso nayonsoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7월 7일 월요일 회의에서 나온 내용대로,

삭제된 댓글에 대해 사용자 정보 JSON 응답할 때 "delete_user" 처럼 마스킹 처리하기.

하는 내용도 이 PR에서 적용 부탁드립니다!! 😊

lsy1307 added 7 commits July 8, 2025 20:39
- Long타입 long으로 수정
- collect -> toList단독으로 변경
- 컨벤션 수정
- Recomment 변경사항 원복
- getGeneralRecommendsExcludingSelected함수 OutOfRange 방지 추가
- UnivApplyInfo University fetchType LAZY로 변경
- 컨벤션 수정
- findRandomByTerm함수 nativeQuery제거 및 Pageable로 LIMIT 구현
- siteUser -> siteUserId로 변경
- 메서드명 각자 기능에 맞게 수정
lsy1307 added 10 commits July 9, 2025 23:29
- 사용하지 않는 import문 제거
- 코드 컨벤션 수정
- postLikeList에서 의미없는 BatchSize 삭제
- password nullable true -> false로 수정
- password nullable 변경사항 취소

This reverts commit 6fcc903.
- 조건문에서 isDeleted사용
- 코드 컨벤션 수정
- 부모 댓글이 삭제된 경우에 자식 댓글이 있는 경우 테스트 코드 추가
- CommentService에서 현재 접속중인 User정보가 아닌 댓글의 User정보를 반환하도록 수정
- DTO에서 구분하여 isDeleted true면 null로 반환
- 테스트 코드 추가
Copy link
Member

@whqtker whqtker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사소한 변경 제안도 긍정적으로 검토해주셔서 감사합니다 ~!

Copy link
Contributor

@Gyuhyeok99 Gyuhyeok99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 ㅎㅎ

Comment on lines 174 to 176
System.out.println("Child1 User ID: " + childComment1.getSiteUserId());
System.out.println("Child2 User ID: " + childComment2.getSiteUserId());
System.out.println("User2 ID: " + user2.getId());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 지워주시면 될 거 같습니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗... 확인하려고 써놓은 걸 깜빡했네요... 수정했습니다!

// when
List<PostFindCommentResponse> responses = commentService.findCommentsByPostId(user1, post.getId());

// then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 코드검증이 저는 개인적으로 좀 읽기 힘들었는데

// then
            PostFindCommentResponse parentResponse = responses.stream()
                    .filter(response -> response.id().equals(parentComment.getId()))
                    .findFirst()
                    .orElseThrow();

            List<PostFindCommentResponse> childResponses = responses.stream()
                    .filter(response -> !response.id().equals(parentComment.getId()))
                    .toList();

            assertAll(
                    () -> assertThat(responses).hasSize(3),
                    () -> assertThat(responses)
                            .extracting(PostFindCommentResponse::id)
                            .containsExactlyInAnyOrder(parentComment.getId(), childComment1.getId(), childComment2.getId()),

                    // 부모 댓글 검증
                    () -> assertThat(parentResponse.content()).isEqualTo(""),
                    () -> assertThat(parentResponse.postFindSiteUserResponse()).isNull(),

                    // 자식 댓글 검증
                    () -> assertThat(childResponses)
                            .extracting(PostFindCommentResponse::content)
                            .containsExactlyInAnyOrder("자식 댓글1", "자식 댓글2"),
                    () -> assertThat(childResponses)
                            .extracting(PostFindCommentResponse::postFindSiteUserResponse)
                            .isNotNull()
                            .extracting(PostFindSiteUserResponse::id)
                            .containsExactlyInAnyOrder(user2.getId(), user2.getId())
            );

이런 느낌으로 좀 나눠가는 건 어떤가요? 반영 안하셔도 괜찮습니다 이건!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 좀 필요없는 것까지 있는 것 같아서 영서님께서 제안해주신 것이랑 같이 확인해서 간결하게 수정해보았습니다!

Copy link
Collaborator

@nayonsoso nayonsoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

바로 approve 드리겠다고 했는데 자꾸 코멘트를 추가해서 죄송합니다.. 😅

"삭제된 사용자"에 대해서는 null 을 응답하겠다는 것은 아직 프론트에 전달되지 않은 것 같으니
제가 디스코드로 여쭤볼게요~
거기에 답변을 해주시면 그때 수정하면 되니까 이 PR은 이만 approve 합니다!
테스트 관련된 내용만 확인해주세요~!

Comment on lines 129 to 134
assertAll(
() -> assertThat(responses).isEmpty(),
() -> assertThat(responses)
.extracting(PostFindCommentResponse::id)
.doesNotContain(parentComment.getId(), childComment1.getId(), childComment2.getId())
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isEmpty 이면, response에 어떤 id도 포함되지 않는다는게 이미 검증 통과된거라 생각해요.
그래서 이렇게 하면 중복 검증이 아닌가? 하는 생각이 드네요.

assertThat(responses).isEmpty(); 만 있어도 충분할 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음...확실히 그렇네요 수정하였습니다!

Comment on lines 185 to 209
assertAll(
() -> assertThat(responses).hasSize(3),
() -> assertThat(responses)
.extracting(PostFindCommentResponse::id)
.containsExactlyInAnyOrder(parentComment.getId(), childComment1.getId(), childComment2.getId()),
() -> assertThat(responses)
.filteredOn(response -> response.id().equals(parentComment.getId()))
.extracting(PostFindCommentResponse::content)
.containsExactly(""),
() -> assertThat(responses)
.filteredOn(response -> response.id().equals(parentComment.getId()))
.extracting(PostFindCommentResponse::postFindSiteUserResponse)
.containsExactly((PostFindSiteUserResponse) null),
() -> assertThat(responses)
.filteredOn(response -> !response.id().equals(parentComment.getId()))
.extracting(PostFindCommentResponse::content)
.containsExactlyInAnyOrder("자식 댓글1", "자식 댓글2"),
() -> assertThat(responses)
.filteredOn(response -> !response.id().equals(parentComment.getId()))
.extracting(PostFindCommentResponse::postFindSiteUserResponse)
.isNotNull()
.extracting(PostFindSiteUserResponse::id)
.containsExactlyInAnyOrder(user2.getId(), user2.getId())
);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertAll(
        () -> assertThat(responses)
                .filteredOn(response -> response.id().equals(parentComment.getId()))
                .extracting(PostFindCommentResponse::postFindSiteUserResponse)
                .containsExactly((PostFindSiteUserResponse) null),
        () -> assertThat(responses)
                .filteredOn(response -> !response.id().equals(parentComment.getId()))
                .extracting(PostFindCommentResponse::postFindSiteUserResponse)
                .isNotNull()
                .extracting(PostFindSiteUserResponse::id)
                .containsExactlyInAnyOrder(user2.getId(), user2.getId())
);

"테스트 코드에서 검증하는 것은 하나여야한다"라는 것을 떠올려보면,
responses의 크기가 3이고, 부모는 빈 내용이지만 자식은 내용이 있는 등.. 은 앞에서 검증한 것이라 여기서 또 검증하지 않아도 된다 생각합니다!

이 테스트코드의 목적에 맞도록, 그리고 이를 읽는 개발자가 검증 내용을 한눈에 파악할 수 있게 이렇게 바꾸는건 어떤가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳이 불필요한 것까지 검증하는 로직이 있었던 것 같습니다...! 좀 더 간결하게 수정하였습니다 : )

lsy1307 added 2 commits July 11, 2025 01:40
- 디버깅용 코드 삭제
- 꼭 필요한 부분만 검증하도록 테스트 검증 간소화
@lsy1307 lsy1307 merged commit cda7a68 into solid-connection:develop Jul 11, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: 댓글 정책 변경관련 수정사항 리팩터링

4 participants